package com.quwan.app.controller;

import com.quwan.anno.AccessCount;
import com.quwan.anno.RecordLog;
import com.quwan.app.service.OrderService;
import com.quwan.app.service.PrePaymentInterface;
import com.quwan.app.vo.*;
import com.quwan.app.vo.pay.BuyItParams;
import com.quwan.app.vo.pay.PrePayment;
import com.quwan.common.BaseController;
import com.quwan.common.Check;
import com.quwan.common.enums.PaymentEnum;
import com.quwan.common.enums.RecordLogApiEnum;
import com.quwan.common.exception.ExpCode;
import com.quwan.common.result.ApiResult;
import com.quwan.common.result.PageResult;
import com.quwan.common.result.ResultCode;
import com.quwan.component.ComponentFactory;
import com.quwan.entity.TSystemPay;
import com.quwan.manager.service.SystemService;
import com.quwan.utils.DateUtils;

import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;


/**
 * @author quan
 * @date 2021-06-10 14:52
 */
@Api(tags = "App订单操作")
@RestController
@RequestMapping("app/order")
@RequiredArgsConstructor
public class OrderController extends BaseController {
    private final OrderService orderService;
    private final SystemService systemService;
    private final ComponentFactory componentFactory;

    @AccessCount
    @RecordLog(RecordLogApiEnum.PUBLISH_ORDER)
    @ApiOperation("会员发布订单")
    @PostMapping("publish")
    public ApiResult publishOrder(HttpServletRequest request, PublishOrderVo params) {
        params.setMId(Long.parseLong(getId(request)));
        if (CollectionUtils.isEmpty(params.getTimeLimit()))
            return ApiResult.error("时间不能空");

        if (StringUtils.isBlank(params.getImgs()))
            return ApiResult.error("图片不能空");

        if (CollectionUtils.isEmpty(params.getCategoryId()))
            return ApiResult.error("分类数据不正确");

        boolean action = orderService.checkPublishOrder(params.getMId());
        Check.state(action,ExpCode.PUBLISH_ORDER_LIMIT);
        if (orderService.memberPublishOrder(params)) {
            return ApiResult.success();
        }

        return ApiResult.failed();
    }

    @ApiOperation("支付开关")
    @GetMapping("pay/power")
    public ApiResult<List<TSystemPay>> payPower() {
        return ApiResult.success(systemService.getPayPowerList());
    }

    @AccessCount
    @ApiOperation("会员下单")
    @PostMapping("buyIt")
    public ApiResult<BuyItOrderDTO> buyIt(HttpServletRequest request,
                                          @ApiParam("发单id") @RequestParam String publishOrderId) {
        return ApiResult.success(orderService.buyIt(publishOrderId, getId(request)));
    }


    @Value("${payment.balance.payUrl}")
    private String payUrl;

    @ApiOperation("支付订单")
    @PostMapping("payOrder")
    public ApiResult<PrePayment> payOrder(HttpServletRequest request, @Validated BuyItParams params) {
        LocalDateTime begin = DateUtils.localDateTimeOfStr(params.getBeginTime());
        //开始时间最低间隔当前3小时
        if (Duration.between(LocalDateTime.now(), begin).toHours() < 3)
            return ApiResult.failed("距离开始时间不足3小时，请预约其他时间哦~");

        final String id = getId(request);
        Check.state(StringUtils.isNotBlank(id), ExpCode.LOGIN_TOKEN_EXPIRED);
        List<TSystemPay> payPowerList = systemService.getPayPowerList();
        TSystemPay pay = null;
        for (TSystemPay power : payPowerList) {
            if (power.getPayKey().equals(params.getPayType())) {
                pay = power;
                break;
            }
        }
        if (pay == null || pay.getStatus() == 0)
            return ApiResult.failed(ExpCode.PAY_NOT_SUPPORT.getMsg());

        PrePaymentInterface payInstance = componentFactory.getPayInstance(PaymentEnum.getByType(params.getPayType()));
        return ApiResult.success(orderService.payOrder(id, params, payInstance));
    }


    @ApiOperation("修改消费订单状态(接单)")
    @PostMapping("changeOrderStatus")
    public ApiResult changeC2cOrderStatus(HttpServletRequest request,
                                          @ApiParam("订单Id") @RequestParam String orderId) {
        if (orderService.changeC2cOrderStatusById(getId(request), orderId))
            return ApiResult.success();

        return ApiResult.error(ExpCode.OPERATE_FAIL);
    }

    @ApiOperation("我发布的订单")
    @PostMapping("memberPublishOrderList")
    public ApiResult<PageResult<PublishOrderSimple>> memberPublishOrderList(HttpServletRequest request,
                                                                            @RequestParam(defaultValue = "1") @ApiParam("1-正常 2已下架") Integer status,
                                                                            @RequestParam int pageNo,
                                                                            @RequestParam int pageSize) {
        return ApiResult.success(orderService.memberPublishOrderList(pageNo, pageSize, getId(request), status));
    }

    @ApiOperation("查看会员发布的订单")
    @PostMapping("catMemberPublishOrderList")
    public ApiResult<PageResult<Map>> memberPublishOrderList(@RequestParam int pageNo,
                                                             @RequestParam int pageSize,
                                                             @ApiParam("目标用户") @RequestParam("id") String target) {
        return ApiResult.success(orderService.catMemberPublishOrderList(pageNo, pageSize, target));
    }

    @ApiOperation("用户订单列表（接单 服务者）")
    @PostMapping("memberServiceOrderList")
    public ApiResult<PageResult<PublishOrderInfo>> memberServiceOrderList(HttpServletRequest request,
                                                                          @RequestParam int pageNo,
                                                                          @RequestParam int pageSize,
                                                                          @ApiParam("0:待接待 1:已接单 2:进行中 3:已完成 4:订单取消 5:中场取消 6:申请退款 7:退款完成") @RequestParam Integer status) {
        return ApiResult.success(orderService.memberServiceOrderList(pageNo, pageSize, getId(request), status));
    }


    @AccessCount
    @ApiOperation("消费订单详情")
    @PostMapping("consumeOrderDetails")
    public ApiResult<ConsumeOrderDetailsDTO> consumeOrderDetails(HttpServletRequest request,
                                                                 @ApiParam("消费订单id") @RequestParam String orderId,
                                                                 @ApiParam("type:0 发单人查询的数据 type:1 下单人查询的数据") @RequestParam String type) {
        return ApiResult.success(orderService.consumeOrderDetails(orderId, type));
    }


    @ApiOperation("用户订单列表（下单 消费者）")
    @PostMapping("memberConsumeOrderList")
    public ApiResult<PageResult<PublishOrderInfo>> memberConsumeOrderList(
            HttpServletRequest request,
            @RequestParam int pageNo,
            @RequestParam int pageSize,
            @ApiParam("0:待接待 1:已接单 2:进行中 3:已完成 4:订单取消 5:中场取消 6:申请退款 7:退款完成") @RequestParam Integer status) {
        return ApiResult.success(orderService.memberConsumeOrderList(pageNo, pageSize, getId(request), status));
    }

    @ApiOperation("评价订单")
    @PostMapping("/commentOrder")
    public ApiResult commentOrder(HttpServletRequest request,
                                  @ApiParam("消费订单id") @RequestParam String orderId,
                                  @ApiParam("0:差评 1:中评 2:好评") @RequestParam String type,
                                  @ApiParam("评论标签") @RequestParam(required = false) List<String> tag,
                                  @ApiParam("评论内容") @RequestParam String commentContent) {
        boolean success = orderService.commentOrder(orderId, type, tag, getId(request), commentContent);
        if (success)
            return ApiResult.success();

        return ApiResult.error(ResultCode.FAIL);

    }

    @ApiOperation("会员订单评价列表")
    @GetMapping("memberOrderCommentList")
    public ApiResult<OrderCommentDTO> memberOrderCommentList(@RequestParam(defaultValue = "1") int pageNo,
                                                             @RequestParam(defaultValue = "10") int pageSize,
                                                             @ApiParam("发单id") @RequestParam String id) {
        return ApiResult.success(orderService.getMemberOrderCommentList(pageNo, pageSize, id));
    }

    @ApiOperation("编辑发单信息")
    @PostMapping("editPublishOrder")
    public ApiResult editPublishOrder(
            HttpServletRequest request,
            @ApiParam("发单id") @RequestParam String publishOrderId,
            @ApiParam("价格") @RequestParam(required = false) String price,
            @ApiParam("年龄要求") @RequestParam(required = false) String ageLimit,
            @ApiParam("性别要求") @RequestParam(required = false) String genderLimit,
            @ApiParam("时间要求  正则校验 7_16:00-18:00(1_08:00-09:00)") @RequestParam(required = false) List<String> timeLimit,
            @ApiParam("简介") @RequestParam(required = false) String otherDesc,
            @ApiParam("图片") @RequestParam(required = false) List<String> url) {
        boolean success = orderService
                .editPublishOrderInfo(getId(request), publishOrderId, price, ageLimit, genderLimit, timeLimit, otherDesc, url);
        if (success)
            return ApiResult.success();

        return ApiResult.error(ResultCode.FAIL);
    }

    @ApiOperation("确认完成订单 请求头需携带token认证身份信息")
    @PostMapping("/confirm")
    public ApiResult confirmOrder(HttpServletRequest request,
                                  @ApiParam("消费订单id") @RequestParam final String id) {

        boolean success = orderService.confirmOrder(getId(request), id);
        if (success)
            return ApiResult.success();

        return ApiResult.failed();
    }

    @ApiOperation("订单取消 请求头需携带token认证身份信息")
    @PostMapping("/cancel")
    public ApiResult cancelOrder(HttpServletRequest request,
                                 @ApiParam("消费订单id") @RequestParam final String id,
                                 @ApiParam("取消原因") @RequestParam String reason) {
        boolean success = orderService.cancelOrder(getId(request), id, reason);
        if (success)
            return ApiResult.success();

        return ApiResult.failed();
    }

    @ApiOperation("我发布的(删除我发布的订单)")
    @PostMapping("/delPo")
    public ApiResult delPublishOrder(HttpServletRequest request,
                                     @ApiParam("发单id") @RequestParam final String id) {
        boolean success = orderService.delPublishOrder(getId(request), id);
        if (success)
            return ApiResult.success();

        return ApiResult.failed();
    }

    @ApiOperation("我发布的(下架我发布的订单)")
    @PostMapping("/hidePo")
    public ApiResult hidePublishOrder(HttpServletRequest request,
                                      @ApiParam("发单id") @RequestParam final String id) {
        boolean success = orderService.hidePublishOrder(getId(request), id);
        if (success)
            return ApiResult.success();

        return ApiResult.failed();
    }

    @ApiOperation("我发布的(编辑内容 数据展示)")
    @PostMapping("/eoContent")
    public ApiResult<EditPublishOrderDTO> editPublishOrderShowData(HttpServletRequest request,
                                                                   @ApiParam("发单id") @RequestParam final String id) {
        return ApiResult.success(orderService.editPublishOrderShowData(getId(request), id));

    }

    @AccessCount
    @ApiOperation("待处理订单数量")
    @PostMapping("await/count")
    public ApiResult<OrderAwaitCountDTO> orderAwaitCount(HttpServletRequest request) {
        return ApiResult.success(orderService.getAwaitProcessOrderCount(getId(request)));

    }


}
